package main

import (
	"fmt"
	"runtime"
	"time"
)

// golang提供了runtime.SetFinalizer函数，当GC准备释放对象时，会回调该函数指定的方法，非常方便和有效。
// 不过值得注意的是，指针构成的 "循环引⽤" 加上 runtime.SetFinalizer 会导致内存泄露。
type Data struct {
	d [1024 * 100]byte
	o *Data
}

func test() {
	var a, b Data
	a.o = &b
	b.o = &a
	runtime.SetFinalizer(&a, func(d *Data) { fmt.Printf("a %p final.\n", d) })
	runtime.SetFinalizer(&b, func(d *Data) { fmt.Printf("b %p final.\n", d) })

}
func main() {
	var a []byte
	for {
		test()
		time.Sleep(time.Millisecond)
		a = make([]byte, 100000)
		for i := 0; i < 1000; i++ {
			a[i] = 1
		}
	}
}

// go build -gcflags "-N -l": https://www.bwangel.me/2022/01/12/go_gcflags/
